1. Field of the Invention
This invention relates generally to object oriented programming and, more particularly, to the dynamic construction of objects of arbitrary class at run time.
2. Description of the Related Art
Three key concepts define object oriented technology in programming: (1) "objects" that encapsulate procedures and data; (2) "messages" that support polymorphism across objects; and (3) "classes" that implement inheritance within class hierarchies. These concepts are well known in the art and are described in many books, such as Object Technology--A Manager's Guide (Second Edition) by David A. Taylor, Ph.D. (First Printing September, 1997).
More particularly, an object is a software element that combines data and related procedures that manipulate that data. Packaging the data and related procedures together is known as encapsulation. The procedures are referred to as "methods" to distinguish them from conventional procedures that are not attached to objects. The data elements are referred to as variables.
FIGS. 1 and 2 represent a generic object and an example of an object that represents a vehicle, such as a truck (with its associated methods and variables). Objects interact with one another by sending messages asking objects to carry out their methods. A message is simply the name of an object followed by the name of a method the object knows how to execute. If a method requires any additional information to know precisely what to do, the message includes that information as a collection of data elements called "parameters." For example, with respect to FIG. 2, a message to the truck object to move to point A would read: Truck (Move to (A)).
The ability of different objects, really different types of objects, to respond to the same message in different ways is called "polymorphism." For example, ship objects, car objects, and plane objects all may implement the method "MoveTo", but each of these three types of objects would implement the method in a different way.
A class is a software template that defines the methods and variables to be included in each instance of an object that is created from the class using its software template. The class specifies a data structure and the permissible methods that apply to each of the objects created from the template. Typically, the data structure comprises numerous pointers that represent a physical address for the location of data, the actual data itself, or both, as shown in FIG. 3. Each class is often uniquely identified by a data value known as a class identifier. An object, then, is an instance of a particular class.
The methods and variables that make up an object are defined only once, in the definition of the class. In any particular application there may be many objects of a certain class. The objects that belong to a class contain only their own particular values for the variables, but all objects of a particular class contain the same methods.
It is possible for one class of objects to be defined as a special case of a more general class. This mechanism or technique is known as "inheritance."
Because an object is made up of methods, data, and pointers, the object as a whole is often not stored in contiguous memory as is shown in FIG. 3. But to facilitate interprocess communication, i.e., transmission between address spaces, or persistence, i.e., storage on non-volatile media, an object is often serialized, or stored in contiguous memory as shown in FIG. 4. Inter-process communication and object persistence are fundamental techniques used in many software applications. After an object has been serialized it is often deserialized, e.g., after the inter-process communication or after retrieval from non-volatile media. Object deserialization is the reconstitution of an object that has been serialized. That is, the object is filled with data, the pointers in the object are set to the address of the data, and the methods of the object are associated with the object.
The first step in object deserialization is to construct an object of arbitrary class. It is desirable for an application, or process, to be able to construct an object of an arbitrary class. This is because an application, or process, during the time that it is executing, may have to interact with an object of a class that was not specified to the application at the time the application was compiled. For example, in FIG. 5 there are shown two computer systems 100 and 200. The computer system 100 has classes 101, 102, and 103 and corresponding objects 1011 and 1021, and 1031. The computer system 200 has classes 201, 202, and 203 together with corresponding objects 2011, 2021, and 2031. During its operation, the computer system 200 communicates the object 2011 to the computer system 100, which is running an application 110. Because the application 110 was compiled only with the classes 101, 102, and 103, the application 110 must construct an object of the class 201 to interact with object 2011. The construction of an object of a class not specified at compile time is referred to as dynamic object construction (as compared to virtual object construction, which is the creation of a new object of the same class as another pre-existing object). The object that is constructed by dynamic object construction is referred to as a subject class.
There currently exist various processes and software packages to perform a limited form of dynamic object construction. One of these is the Microsoft Component Object Model ("COM") architecture. Instead of providing a substantially generic dynamic object construction methodology, however, COM requires that each subject class implement what is known as the IUnknown interface. This so-called interface, IUnknown, is essentially a set of three processes, one of which is a process of invoking an actual interface. In other words, the IUnknown interface really is not an interface. It is the "actual" interface that allows the subject class, and each object instance of that class, to be called on by other objects or applications. Because each subject class in the COM architecture must implement the non-standard IUnknown interface, as well as at least one other predefined interface (the actual interface), the COM architecture is not truly generic.
In addition to the foregoing limitation, COM requires each class be assigned a 128-bit class identifier or globally unique identifier ("GUID"). Once again, by requiring a GUID of a specific size, and of a substantially large size, COM places additional limitations on dynamic object construction making COM less generic.
Not only must each class have a 128-bit GUID in COM, but each class identifier, or GUID, must be registered in the system registry, i.e., a persistent centralized database. Moreover, there must be one and only one program to export an entry-point (this program is known as the IClassFactory interface) to construct objects of the subject class. That is, there must be one and only one program that creates instances of objects of a subject class. In other words, in COM, there must exist only one IClassFactory for each subject class.
Yet another limitation is that the COM interfaces that specify the serialization architecture (known as IPersist*) also imply that the serial representation of objects must contain the 128-bit GUID class identifier, which can add unnecessarily to the size of the protocol data units transmitted by the network. Also, requiring class identifiers to appear in the system registry creates install-time complications, makes it difficult for multiple program versions to co-exist, and can reveal proprietary implementation details to reverse engineers.
The Microsoft Foundation Classes ("MFC") software developers kit provides a technique for dynamic object construction. This technique is inseparably bound with MFC object persistence. Object persistence refers to the concept of maintaining objects over time and reusing them whenever a program is run. For each subject class, MFC object persistence requires that the subject class derive from a common base class known as CObject. In addition, the subject class must implement at least one member function or method (known as GetRuntimeClass). Finally, the subject class must be serialized and deserialized via a proprietary CArchive object. In addition to these limitations, MFC object persistence requires that the name string of the subject class be used as the class identifier. And MFC supports only a single global class information database. Moreover, MFC doesn't give the programmer access to the class information database. Finally, because MFC is an application level class library, its sheer size militates against its use by system software components.
Still another application that provides limited dynamic object construction capability is the C++ class library known as Rogue Wave Tools.H++. This product provides dynamic object construction through its RWFactory class. But in similar fashion to COM and MFC, Rogue Wave fools.H++ is organized such that for each subject class, RWFactory requires that the subject class derive from a common base class known as RWCollectable. In addition, the subject class may only be identified by a 16-bit unsigned integer. And the subject class must implement five specific methods. Finally, the subject class must be registered with a single global factory object.
All three of these alternatives require that subject classes derive from a common base class, or that the subject classes implement specific non-standard methods, with the consequences that they can not be used with pre-existing class hierarchies that don't comply with these requirements and intrude unacceptably into the design of subject class hierarchies.
The present invention is directed to overcoming, or at least reducing the effects of one or more of the problems set forth above.